/*
 * RestHttpHandler.h
 *
 *  Created on: 2018年2月9日
 *      Author: terry
 */

#ifndef RESTHTTPHANDLER_H_
#define RESTHTTPHANDLER_H_

#include "HttpServer.h"
#include "CHttpTokenAuth.h"
#include <functional>
#include <map>


class RestHttpHandler : public HttpHandler
{
public:
	typedef std::function<int(HttpRequest&, std::string&)> 	HttpProcessor;

public:
	RestHttpHandler();
	virtual ~RestHttpHandler();

	void setUserStore(HttpUserStorePtr store);

	void setup(const std::string& uri, HttpProcessor proc);

	void setup(const std::string& uri, bool acquireAuth, HttpProcessor proc);

	void setup(const std::string& uri, const std::string& method, HttpProcessor proc);
	void setup(const std::string& uri, const char* method, HttpProcessor proc);

	void setup(const std::string& uri, const std::string& method, bool acquireAuth, HttpProcessor proc);
	void setup(const std::string& uri, const char* method, bool acquireAuth, HttpProcessor proc);

	virtual int handleJsonApi(HttpRequest& request, std::string& json);

	bool checkAuth(HttpRequest& request, std::string& jsonText);

	int login(HttpRequest& request, std::string& jsonText);
	int logout(HttpRequest& request, std::string& jsonText);

public:
	static int setError(int code, const std::string& message, std::string& jsonText);
	static size_t split(const mg_str& str, char sep, std::string& head, std::string& tail);

protected:
	bool getToken(HttpRequest& request, std::string& token);

	bool getUser(HttpRequest& request, std::string& username);

protected:
	struct ProcessorEntry
	{
		std::string uri;
		std::string method;
		bool auth;
		HttpProcessor processor;

		ProcessorEntry():
			auth()
		{
		}

		ProcessorEntry(const std::string& uri, const std::string& method, HttpProcessor processor):
			auth()
		{
			this->uri = uri;
			this->method = method;
			this->processor = processor;
		}
	};

	typedef std::map< std::string, ProcessorEntry >	HttpProcessorMap;
	typedef std::map< std::string, HttpProcessorMap> ProcessorTable;

	bool findProcessor(HttpRequest& request, ProcessorEntry& entry);

	bool matchEntry(HttpRequest& request, const std::string& pattern, StringMap& params);

	ProcessorTable::const_iterator findEntry(HttpRequest& request, StringMap& params);

protected:
	CHttpTokenAuth	m_auth;
	ProcessorTable	m_procTable;

};

#endif /* RESTHTTPHANDLER_H_ */
